package com.hxzy.tms.service.impl;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.hxzy.tms.HibernateSessionHolder;
import com.hxzy.tms.SessionHolder;
import com.hxzy.tms.dao.UserDao;
import com.hxzy.tms.entity.User;
import com.hxzy.tms.service.ServiceResult;
import com.hxzy.tms.service.UserService;
/**
 * 用户Service实现类
 * @author team1
 */
public class DefaultUserService implements UserService {
	private final Logger logger = LoggerFactory.getLogger(getClass());
	private UserDao userDao;
	public boolean checkEmail(String email) {
		// TODO Auto-generated method stub
		return false;
	}

	

	public ServiceResult<User> register(String email, String passwd,String username, String nickname, String realname, long mobile,
			String vercode, String ip) {
		//检查邮箱是否存在
		Map<String,Object> param = new HashMap<String, Object>();
		param.put("email", email);
		List<User> users = userDao.read("from User where email = :email", param);
		if(!users.isEmpty()){
			return new ServiceResult<User>(-1,null,"邮箱已经存在");
		}
		//检查手机号是否存在
		param = new HashMap<String, Object>();
		param.put("phone", mobile);
		users = userDao.read("from User where phone =:phone", param);
		if(!users.isEmpty()){
			return new ServiceResult<User>(-2,null,"手机号已经存在");
		}
		
		User user = new User();
		
		user.setUsername(username);
		user.setSalt(createSalt());
		user.setPasswd(DigestUtils.sha256Hex((user.getSalt()+ passwd).getBytes()));
		user.setRealname(realname);
		user.setNickname(nickname);
		user.setPhone(mobile);
		user.setEmail(email);
		user.setGmtCreate(System.currentTimeMillis() / 1000);
		user.setGmtModified(user.getGmtCreate());
		user.setIpReg(ip);
		user.setStatus(1L);
		user.setRoot(0);
		
		userDao.create(user);
		
		logger.info("新用户注册",user.getUsername());
		
		return new ServiceResult<User>(1,null,"注册成功");
	}

	public User getInfo(String email) {
		// TODO Auto-generated method stub
		return null;
	}

	

	public ServiceResult<String> generateSessionHash(String ip) {
        long sessionUser = SessionHolder.get().getId();
        int s = RandomUtils.nextInt(10000, 99999); // 随机数

        String hash = DigestUtils.sha256Hex((s + ip).getBytes());
        User user = userDao.read(User.class, sessionUser);
         user.setHash(hash);
        long hashExpires = (System.currentTimeMillis() / 1000) + 7 * 24 * 60 * 60;
        user.setGmtHashExpires(hashExpires); // 超时时间是 7 天
        if (userDao.update(user) == 1) {
            return new ServiceResult<String>(1, hash);
        } else {
            return new ServiceResult<String>(-2, null, "数据库错误");
        }
	}

	public ServiceResult<User> getUser(String hash, String ip) {
		 if (StringUtils.isBlank(hash) || StringUtils.isBlank(ip)) {
	            return new ServiceResult<User>(1, null);
	        }
	        if (HibernateSessionHolder.get() != null) {
	            return new ServiceResult<User>(1, SessionHolder.get());
	        }

	        if (StringUtils.isEmpty(ip) || StringUtils.isEmpty(hash)) {
	            return new ServiceResult<User>(1, null);
	        }

	        Map<String, Object> param = new HashMap<String, Object>();
	        param.put("hash", hash);
	        param.put("gmt_hash_expires", (System.currentTimeMillis() / 1000));
	        List<User> users = userDao.read("from User where hash = :hash and gmt_hash_expires > :gmt_hash_expires ", param);
	        if (users.isEmpty()) {
	            return new ServiceResult<User>(1, null);
	        }

	        User user = users.get(0);

	        if (!ip.equals(user.getIpLogin())) { // 如果换 ip 了就当没有登录过啦，TODO 要清空 hash
	            return new ServiceResult<User>(1, null);
	        }

	        User userInSession = new User();
	        userInSession.setId(user.getId());
	        userInSession.setNickname(user.getNickname());
	        return new ServiceResult<User>(1, userInSession);
	}
	public User login(String email, String passwd, String ip) {
		if (StringUtils.isBlank(email) || StringUtils.isBlank(passwd) || StringUtils.isBlank(ip)) {
            return null;
        }
		//1.先尝试邮箱登录
		try {
			Map<String,Object> param = new HashMap<String, Object>();
			param.put("email", email);
			List<User> users = userDao.read("from User where email=:email", param);
			if (users.isEmpty() || users.size() > 1) {
                return null;
            }
			
			if (users.size() > 1) {
                logger.error("{} 匹配到 {} 条用户记录 {} ", email, users.size());
                return null;
            }
			User user = users.get(0);
			if (user == null || !user.getPasswd().equals(DigestUtils.sha256Hex((user.getSalt() + passwd).getBytes()))) { // 加密比对
                logger.error("{} 尝试登录但密码错误", email);
                return null;
            	}
			long now =(System.currentTimeMillis() / 1000);
			user.setGmtLogin(now);
			user.setIpLogin(ip);
			user.setGmtModified(now);
			
			userDao.saveOrUpdate(user);
			
			User userInSession = new User();
			userInSession.setId(user.getId());
			userInSession.setNickname(user.getNickname());
			
			SessionHolder.set(userInSession);
			
			return userInSession;
			} catch (Exception e) {
			logger.error("登錄失敗",e);
		}
		return null;
	}
	public void logout() {
		if(SessionHolder.get() != null){
			User user = userDao.read(User.class, SessionHolder.get().getId());
			user.setHash("");
			user.setGmtHashExpires(0L);
			userDao.saveOrUpdate(user);
			SessionHolder.clear();
		}
		
	}
	
	private String createSalt() {
        Random ranGen = new SecureRandom();
        byte[] aesKey = new byte[32];
        ranGen.nextBytes(aesKey);
        StringBuffer hexString = new StringBuffer();
        for (int i = 0; i < aesKey.length; i++) {
            String hex = Integer.toHexString(0xff & aesKey[i]);
            if (hex.length() == 1)
                hexString.append('0');
            hexString.append(hex);
        }
        return hexString.toString();
    }
	
	public UserDao getUserDao() {
		return userDao;
	}

	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

}